Adding Pagination To Vapor Query
When you have a request that returns many records, it’s almost required to paginate the response.
I found this QueryContainer extension that does just that:
QueryContainer extension
import Foundation
import Vapor
import Fluent
public struct BasicQuery: Codable {
public let plain: Bool?
public let page: Int?
public let limit: Int?
public let search: String?
}
extension QueryContainer {
public var basic: BasicQuery? {
let decoded = try? decode(BasicQuery.self)
return decoded
}
public var plain: Bool? {
return basic?.plain
}
public var page: Int? {
return basic?.page
}
public var limit: Int? {
return basic?.limit ?? 20
}
public var search: String? {
return basic?.search
}
}
//GET http://localhost:8080/api/countries?limit=20&page=1
extension QueryBuilder {
public func paginate(on req: Request) throws -> Self {
if let limit = req.query.basic?.limit {
let page = req.query.basic?.page ?? 0
let lower = (page * limit)
return range(lower: lower, upper: (lower + limit))
}
return self
}
}
Implementation
//GET /api/countries
aRoute.get(use: getAllPaginatedHandler)
...
func getAllPaginatedHandler(_ req: Request) throws -> Future<[CountrySQLite]> {
return try CountrySQLite.query(on: req).paginate(on: req).all()
}
Usage
To fetch 10th page, given that a page size is 20 records:
GET http://localhost:8080/api/countries?limit=20&page=10
You may checkout the full example on GitHub:
Prev: Parent-Child relationships in Generic Fluent Models
Next: Revert Last Migration